﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Model;
using FinalPointSet.Model.Model.MockData;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using static FinalPointSet.Model.Manager.MessageManager;

namespace FinalPointSet.ViewModel.Page.MockData
{
    public partial class MockRuleSettingPageViewModel : ObservableObject
    {
        /// <summary>
        /// 当前选中的元素
        /// </summary>
        [ObservableProperty]
        private MockRule? _MockRule;
        /// <summary>
        /// 运行结果
        /// </summary>
        [ObservableProperty]
        private string _OutputResult = "";
        /// <summary>
        /// 生成规则
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<MockRule> _MockRules = [];
        /// <summary>
        /// 显示/隐藏抽屉视图
        /// </summary>
        [ObservableProperty]
        private bool _IsDrawerOpen = false;
        /// <summary>
        /// 当前运行的规则
        /// </summary>
        [ObservableProperty]
        private MockRule _RunMockRule = new();
        /// <summary>
        /// 当前运行的参数的模板
        /// </summary>
        [ObservableProperty]
        private MockParamTemplate? _RunMockParamTemplate;
        /// <summary>
        /// 扩展参数
        /// </summary>
        [ObservableProperty]
        private string _ExtraParma = string.Empty;
        /// <summary>
        /// 默认扩展参数值
        /// </summary>
        private readonly string _DefaultExtraParma = "fieldName=field&startIndex=1&endIndex=3";
        public MockRuleSettingPageViewModel()
        {
            List<MockRule> datas = AssetManager.Instance.GetJsonObjectList<MockRule>() ?? [];
            MockRules = new ObservableCollection<MockRule>(datas);
        }

        #region 规则页面命令
        /// <summary>
        /// 打开抽屉视图
        /// </summary>
        [RelayCommand]
        private void OpenDrawer(MockRule mockRule)
        {
            Debug.Print($"SettingPageViewModel.OpenDrawer(), mockRule={mockRule?.Name}");
            if (mockRule == null)
                return;

            RunMockParamTemplate = null;
            OutputResult = string.Empty;
            ExtraParma = _DefaultExtraParma;
            RunMockRule = mockRule;
            IsDrawerOpen = true;
        }

        /// <summary>
        /// 运行规则
        /// </summary>
        [RelayCommand]
        private void Run()
        {
            Debug.Print($"SettingPageViewModel.Run(), RunMockRule={RunMockRule?.Name}");
            if (RunMockRule == null)
                return;

            OutputResult = string.Empty;
            //将附加属性转换为字典
            Dictionary<string, string> extraParmaDict = [];
            try
            {
                string[] extraParmas = ExtraParma.Split("&");
                foreach (string parma in extraParmas)
                {
                    string[] pair = parma.Split("=");
                    if (pair.Length > 1)
                    {
                        extraParmaDict.TryAdd(pair[0], pair[1]);
                    }
                    else
                    {
                        extraParmaDict.TryAdd(pair[0], string.Empty);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Print($"SettingPageViewModel.Run(), 解析附加属性失败, 失败原因:{e.Message}");
                //获取结果
                OutputResult = $"解析附加属性失败, 失败原因:{e.Message}";
                return;
            }

            if (RunMockParamTemplate == null)
            {
                Debug.Print("SettingPageViewModel.Run(), 请选择参数模板后再运行!");
                OutputResult = "请选择参数模板后再运行!";
                return;
            }

            try
            {
                //序列化输入的参数
                string jsonArg = RunnableScriptHelper.SerSerializeInput(RunMockParamTemplate?.Value ?? "", extraParmaDict);
                //获取结果
                OutputResult = RunnableScriptHelper.GenerateWithLog(RunMockRule, jsonArg);
            }
            catch (Exception e)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"运行规则失败!, 失败原因:{e.Message}"));
            }
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        [RelayCommand]
        private void Add()
        {
            if (MockRules == null)
                return;

            int maxID = MockRules.Count > 0 ? MockRules.Max(e => e.ID + 1) : 1001;
            MockRule mockRule = new()
            {
                ID = maxID,
                Name = $"规则{MockRules.Count + 1}",
                ParamTemplates = [new MockParamTemplate { Name = "默认" }]
            };
            MockRules?.Add(mockRule);
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"新增规则[{mockRule.Name}]成功!"));
            Debug.Print($"MockDataSettingViewModel.Add(), 新增规则[{mockRule.Name}]成功!");
        }

        /// <summary>
        /// 保存
        /// </summary>
        [RelayCommand]
        private void Save()
        {
            if (MockRules == null)
            {
                Debug.Print("MockDataSettingViewModel.Save(),知识点数据为空");
                return;
            }
            AssetManager.Instance.UpdateJsonObjectList(MockRules.ToList());
            AssetManager.Instance.SaveJsonObjectList<MockRule>();
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"保存{MockRules.Count}条数据成功!"));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="MockRule">自定义脚本</param>
        [RelayCommand]
        private void Delete(MockRule mockRule)
        {
            if (mockRule == null || MockRules == null)
                return;
            Debug.Print($"MockDataSettingViewModel.Delete(), 删除规则[{mockRule.Name}]成功!");
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"删除规则[{mockRule.Name}]成功!"));
            //删除源数据和匹配的数据
            MockRules.Remove(mockRule);
        }
        #endregion

        #region 参数模板
        /// <summary>
        /// 增加参数模板
        /// </summary>
        [RelayCommand]
        private void AddParam()
        {
            if (MockRule == null)
            {
                Debug.Print($"MockDataSettingViewModel.AddParam(), 请先选择规则后再添加参数模板!");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "请先选择规则后再添加参数模板!"));
                return;
            }

            int maxSeq = MockRule.ParamTemplates.Count > 0 ? MockRule.ParamTemplates.Max(e => e.Sequence) + 1 : 1;
            MockParamTemplate mpt = new()
            {
                Sequence = maxSeq,
                Name = $"模板{MockRule.ParamTemplates.Count + 1}"
            };
            MockRule.ParamTemplates.Add(mpt);
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"新增参数模板[{mpt.Name}]成功!"));
            Debug.Print($"MockDataSettingViewModel.AddParam(),新增参数模板:{mpt.Name}, Sequence={maxSeq}");
        }

        /// <summary>
        /// 删除参数模板
        /// </summary>
        /// <param name="MockParamTemplate">参数模板</param>
        [RelayCommand]
        private void DeleteParam(MockParamTemplate mpt)
        {
            if (mpt == null || MockRule == null)
                return;
            Debug.Print($"MockDataSettingViewModel.DeleteParam(), 删除参数模板[{mpt.Name}]成功!");
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"删除参数模板[{mpt.Name}]成功!"));
            //删除源数据和匹配的数据
            MockRule.ParamTemplates.Remove(mpt);
        }

        /// <summary>
        /// 上移参数模板
        /// </summary>
        [RelayCommand]
        private void MoveUpParam(MockParamTemplate mpt)
        {
            if (mpt == null || MockRule == null)
                return;
            int index = MockRule.ParamTemplates.IndexOf(mpt);
            if (index <= 0)
            {
                Debug.Print($"MockDataSettingViewModel.MoveUpParam(), 当前参数模板已位于最顶部, 无法移动");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "当前参数模板已位于最顶部, 无法移动"));
                return;
            }
            //交换排序索引
            (MockRule.ParamTemplates[index].Sequence, MockRule.ParamTemplates[index - 1].Sequence) = (MockRule.ParamTemplates[index - 1].Sequence, MockRule.ParamTemplates[index].Sequence);
            List<MockParamTemplate> mpts = new(MockRule.ParamTemplates.ToList().OrderBy(e => e.Sequence));
            MockRule.ParamTemplates.Clear();
            foreach (MockParamTemplate element in mpts)
            {
                MockRule.ParamTemplates.Add(element);
            }
            Debug.Print($"MockDataSettingViewModel.MoveUpParam(), 上移参数模板:{mpt.Name}");
        }

        /// <summary>
        /// 下移数据源
        /// </summary>
        [RelayCommand]
        private void MoveDownParam(MockParamTemplate mpt)
        {
            if (mpt == null || MockRule == null)
                return;
            int index = MockRule.ParamTemplates.IndexOf(mpt);
            if (index >= MockRule.ParamTemplates.Count - 1)
            {
                Debug.Print($"MockDataSettingViewModel.MoveDownParam(), 当前参数模板已位于最底部, 无法移动");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "当前参数模板已位于最底部, 无法移动"));
                return;
            }
            //交换排序索引
            (MockRule.ParamTemplates[index].Sequence, MockRule.ParamTemplates[index + 1].Sequence) = (MockRule.ParamTemplates[index + 1].Sequence, MockRule.ParamTemplates[index].Sequence);
            List<MockParamTemplate> mpts = new(MockRule.ParamTemplates.ToList().OrderBy(e => e.Sequence));
            MockRule.ParamTemplates.Clear();
            foreach (MockParamTemplate element in mpts)
            {
                MockRule.ParamTemplates.Add(element);
            }
            Debug.Print($"MockDataSettingViewModel.MoveDownParam(), 下移参数模板:{mpt.Name}");
        }
        #endregion
    }
}
